﻿using System;
using MarriageFertility.Behaviors;
using MarriageFertility.Helpers;
using MarriageFertility.Mcm;
using MarriageFertility.Missions;
using MarriageFertility.Notifications;
using MarriageFertility.Texts;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.GameMenus;
using TaleWorlds.Core;
using TaleWorlds.Localization;

namespace MarriageFertility.Dialogs
{
    public static class PregnancyDialog
    {
        private const int RelationIncreaseOnAgree = 10;
        private const int RelationDecreaseOnForce = -20;
        private const double GoldPercentage = 0.1;

        public static void AddDialogs(CampaignGameStarter campaignGameStarter)
        {
            AddPregnancyServiceDialogs(campaignGameStarter);
        }

        private static void AddPregnancyServiceDialogs(CampaignGameStarter campaignGameStarter)
        {
            campaignGameStarter.AddPlayerLine("pregnancy_service_start", "hero_main_options",
                "pregnancy_service_request",
                PregnancyText.ServiceStartText.ToString(), CanPregnancyService, null);

            campaignGameStarter.AddDialogLine("pregnancy_service_agree", "pregnancy_service_request", "hero_leave",
                PregnancyText.ServiceAgreeText.ToString(), AgreePregnancyService, PregnancyServiceStart);

            campaignGameStarter.AddDialogLine("pregnancy_service_polite_deny", "pregnancy_service_request",
                "pregnancy_deny_request",
                PregnancyText.ServicePoliteDenyText.ToString(), CanPolitelyDenyPregnancyService, null);

            campaignGameStarter.AddDialogLine("pregnancy_service_deny", "pregnancy_service_request",
                "pregnancy_deny_request",
                PregnancyText.ServiceDenyText.ToString(), CanStronglyDenyPregnancyService, null);

            campaignGameStarter.AddPlayerLine("pregnancy_service_force", "pregnancy_deny_request",
                "pregnancy_service_force",
                PregnancyText.ServiceForceText.ToString(), CanPregnancyService, null);

            campaignGameStarter.AddPlayerLine("pregnancy_service_leave", "pregnancy_deny_request", "hero_leave",
                PregnancyText.ServiceLeaveText.ToString(), null, null);

            campaignGameStarter.AddDialogLine("pregnancy_service_force_start", "pregnancy_service_force",
                "close_window",
                PregnancyText.ServiceForceStartText.ToString(), null, ForcePregnancyService);
        }

        private static bool CanPregnancyService()
        {
            Hero hero = Hero.OneToOneConversationHero;
            return MCMSettings.Instance.EnableSexPregnancyDialog &&
                   hero != null && hero.IsFemale && !hero.IsPregnant && !hero.IsPlayerSpouse() &&
                   hero.Age >= MCMSettings.Instance.MinPregnancyAge && hero.Age <= MCMSettings.Instance.MaxPregnancyAge;
        }

        private static void PregnancyServiceStart()
        {
            Hero hero = Hero.OneToOneConversationHero;
            PregnancyStart(hero, RelationIncreaseOnAgree);
        }

        private static void PregnancyStart(Hero hero, int relationChange)
        {
            CustomerPregnancyCampaignBehavior pregnancyBehavior =
                Campaign.Current.GetCampaignBehavior<CustomerPregnancyCampaignBehavior>();
            if (pregnancyBehavior != null)
            {
                try
                {
                    hero.IsPregnant = true;
                    pregnancyBehavior.RecordPregnancyData(hero, Hero.MainHero);
                    GiveGoldAction.ApplyBetweenCharacters(hero, Hero.MainHero, (int)(hero.Gold * GoldPercentage));
                    TextObject message = MessageText.PregnancyServiceMessage;
                    message.SetTextVariable("hero", hero.Name);
                    MBInformationManager.AddQuickInformation(message);
                    ChangeRelationAction.ApplyPlayerRelation(hero, relationChange);
                    hero.SetHasMet();
                    if (RelationHelper.HotButterFound)
                    {
                        MBInformationManager.ShowSceneNotification(new HotButterNotification(Hero.MainHero, hero, hero.CurrentSettlement, null));
                    }
                }
                catch (Exception e)
                {
                    Log.ErrorMessage(e.Message);
                }
            }
        }

        private static bool AgreePregnancyService()
        {
            Hero hero = Hero.OneToOneConversationHero;
            return hero != null && hero.GetRelationWithPlayer() > 30;
        }

        private static bool CanPolitelyDenyPregnancyService()
        {
            Hero hero = Hero.OneToOneConversationHero;
            return hero != null && hero.GetRelationWithPlayer() >= 0 && hero.GetRelationWithPlayer() < 30;
        }

        private static bool CanStronglyDenyPregnancyService()
        {
            Hero hero = Hero.OneToOneConversationHero;
            return hero != null && hero.GetRelationWithPlayer() < 0;
        }

        private static void ForcePregnancyService()
        {
            Hero hero = Hero.OneToOneConversationHero;
            if (hero != null)
            {
                DuelManager.DuelFightResult = DuelManager.DuelFightResultEnum.None;
                DuelManager.DuelHero = hero.CharacterObject;
                DuelManager.WinCallEvent = () => PregnancyStart(hero, RelationDecreaseOnForce);
                DuelManager.LoseCallEvent =
                    () => ChangeRelationAction.ApplyPlayerRelation(hero, RelationDecreaseOnForce);
                
                TextObject duelMessage = PregnancyText.ForcePregnancyDuelMessage.SetTextVariable("HERO_NAME", hero.Name.ToString());
                DuelManager.DuelMenuTitle = duelMessage.ToString();

                DuelManager.DuelFightType = DuelManager.DuelFightTypeEnum.Single;
                GameMenu.SwitchToMenu(DuelManager.MdMenu);
            }
        }
    }
}